package org.luckyjourney.service.user.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.lettuce.core.support.caching.RedisCache;
import org.luckyjourney.constant.RedisConstant;
import org.luckyjourney.entity.regularusers.RegularUsers;
import org.luckyjourney.entity.user.Follow;
import org.luckyjourney.entity.user.User;
import org.luckyjourney.entity.vo.BasePage;
import org.luckyjourney.entity.vo.FollowVO;
import org.luckyjourney.entity.vo.UserVO;
import org.luckyjourney.exception.BaseException;
import org.luckyjourney.mapper.FileMapper;
import org.luckyjourney.mapper.FollowMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.luckyjourney.mapper.regularusers.RegularUsersMapper;
import org.luckyjourney.mapper.user.UserMapper;
import org.luckyjourney.service.FeedService;
import org.luckyjourney.service.user.FollowService;
import org.luckyjourney.service.user.UserService;
import org.luckyjourney.service.video.VideoService;
import org.luckyjourney.util.RedisCacheUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.security.DenyAll;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xhy
 * @since 2023-10-25
 */
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements FollowService {

    @Autowired
    private FeedService feedService;

    @Autowired
    @Lazy
    private VideoService videoService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisCacheUtil redisCacheUtil;
    @Autowired
    UserService userService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    FollowMapper followMapper;
    @Autowired
    RegularUsersMapper regularUsersMapper;

    @Override
    public int getFollowCount(Long userId) {
        return count(new LambdaQueryWrapper<Follow>().eq(Follow::getUserId, userId));
    }

    @Override
    public int getFansCount(Long userId) {
        //获取自己的类型id
        //死循环更换userMapper
        User user = userMapper.selectById(userId);
        Integer ModuleId = user.getModuleId();

        Follow follow = new Follow();
        //获取自己的id  反向查询  关注人的id 跟类型id 查询出自己的粉丝
        follow.setFollowId(userId);
        follow.setModuleId(ModuleId);
        LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Follow::getFollowId, userId).eq(Follow::getModuleId, ModuleId);
        Integer integer = followMapper.selectCount(queryWrapper);
        return integer;
    }

    /**
     * ...
     * @param userId
     * @param basePage
     * @return
     */
    @Override
    public List<Follow> getFollow(Long userId, BasePage basePage) {
        //根据自己的id跟类型查询出关注列表
        UserVO userVO = userService.getInfo(userId);
        Integer ModuleId = userVO.getModuleId();
        Follow follow = new Follow();
        follow.setUserId(userId);
        follow.setMyselfId(ModuleId);
        List<Follow> follows = followMapper.selectListPage(follow);
        if (ObjectUtils.isEmpty(follows)) {
            return Collections.EMPTY_LIST;
        }
        return follows;


    }


    @Override
    public List<Follow> getFans(Long userId, BasePage basePage) {

        //获取自己的类型id
        UserVO userVO = userService.getInfo(userId);
        Integer ModuleId = userVO.getModuleId();
        Follow follow = new Follow();
        //获取自己的id  反向查询  关注人的id 跟类型id 查询出自己的粉丝
        follow.setFollowId(userId);
        follow.setModuleId(ModuleId);
        //粉丝
        List<Follow> follows = followMapper.Page(follow);
        if (ObjectUtils.isEmpty(follows)) {
            return Collections.EMPTY_LIST;
        }
        return follows;

    }

    @Override
    public Boolean follows(Long followsId, Long userId, Integer moduleId) {
        //通过自己的id查询
        UserVO userVO = userService.getInfo(userId);
        //获取自己的类型id
        Integer MyselfId = userVO.getModuleId();

        //判断自己的id是否等于关注人的id  自己的类型id是否等于关注人的类型id
        if (followsId.equals(userId) && MyselfId == moduleId) {
            throw new BaseException("你不能关注自己");
        }
        // 直接保存(唯一索引),保存失败则删除
        final Follow follow = new Follow();
        //对方的id
        follow.setFollowId(followsId);
        //自己的id
        follow.setUserId(userId);
        //关注人的类型id
        follow.setModuleId(moduleId);
        //自己的类型id
        follow.setMyselfId(MyselfId);
        try {
            save(follow);
            final Date date = new Date();
            // 自己关注列表添加
            redisTemplate.opsForZSet().add(RedisConstant.USER_FOLLOW + userId, followsId, date.getTime());
            // 对方粉丝列表添加
            redisTemplate.opsForZSet().add(RedisConstant.USER_FANS + followsId, userId, date.getTime());
        } catch (Exception e) {
            // 删除收件箱的视频
            // 获取关注人的视频
            final List<Long> videoIds = (List<Long>) videoService.listVideoIdByUserId(followsId);
            if (!ObjectUtils.isEmpty(videoIds)) {
                feedService.deleteInBoxFeed(userId, videoIds);
            }
            // 自己关注列表删除
            redisTemplate.opsForZSet().remove(RedisConstant.USER_FOLLOW + userId, followsId);
            // 对方粉丝列表删除
            redisTemplate.opsForZSet().remove(RedisConstant.USER_FANS + followsId, userId);
            // 删除
            remove(new LambdaQueryWrapper<Follow>().eq(Follow::getFollowId, followsId).eq(Follow::getUserId, userId));
            return false;
        }

        return true;
    }

    @Override
    public Boolean isFollows(Long followId, Long userId) {
        if (userId == null || followId == null) {
            return false;
        }

        return count(new LambdaQueryWrapper<Follow>().eq(Follow::getFollowId, followId).eq(Follow::getUserId, userId)) == 1;
    }

    @Override
    public List<Follow> selectFollow(Follow follow) {

        List<Follow> follows = followMapper.select(follow);

        return follows;
    }

    @Override
    public long getFansCountUser(Long userId) {
        //获取自己的类型id
        RegularUsers user = regularUsersMapper.selectById(userId);
        Integer ModuleId = user.getModuleId();
        Follow follow = new Follow();
        follow.setFollowId(userId);
        follow.setModuleId(ModuleId);
        LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Follow::getFollowId, userId).eq(Follow::getModuleId, ModuleId);
        Integer integer = followMapper.selectCount(queryWrapper);
        return integer;
    }

    @Override
    public List<Long> getFollowId(Long currentId, Integer moduleId) {
        Follow follow = new Follow();
        follow.setUserId(currentId);
        follow.setMyselfId(moduleId);
        return followMapper.getFollowId(follow);
    }

    @Override
    public long getFansCountPs(Long userId) {
        //获取自己的类型id
        //死循环更换userMapper
        RegularUsers user = regularUsersMapper.selectById(userId);
        Integer ModuleId = user.getModuleId();

        Follow follow = new Follow();
        //获取自己的id  反向查询  关注人的id 跟类型id 查询出自己的粉丝
        follow.setFollowId(userId);
        follow.setModuleId(ModuleId);
        LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Follow::getFollowId, userId).eq(Follow::getModuleId, ModuleId);
        Integer integer = followMapper.selectCount(queryWrapper);
        return integer;

    }


}
